package cc.verywell.pureblock.util.sign;

import java.nio.ByteBuffer;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.ShortBufferException;
import javax.crypto.spec.SecretKeySpec;

import cc.verywell.pureblock.log.Pblog;
import cc.verywell.pureblock.util.EncryptUtil;

/**
* 
* see https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#KeyGenerator
* 
* @author TanYaqiu 
* @address flat 601
* @date 2019年2月25日 上午12:39:36
*/
public class Aes128raw implements EncryptUtil {

	final private SecretKey key;
	final private Cipher encode,decode;
	public Aes128raw() {
		this(genKey());
	}
	public Aes128raw(byte[] key) {
		this(new SecretKeySpec(key,"AES"));
	}
	public Aes128raw(SecretKey skey) {
		this.key = skey;
		try {
			Cipher cipher;
			this.encode = cipher = Cipher.getInstance("AES");// 创建密码器
			cipher.init(Cipher.ENCRYPT_MODE, skey);// 初始化加密器
			this.decode = cipher = Cipher.getInstance("AES");// 创建密码器
			cipher.init(Cipher.DECRYPT_MODE, skey);// 初始化加密器
		} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException e) {
			if(Pblog.INIT)Pblog.INIT(e);
			throw new RuntimeException(e);
		}
	}
	  
	/**
	 * 
	 * @return AES 密码
	 */
	private static SecretKey genKey() {
        KeyGenerator kgen;
		try {
			kgen = KeyGenerator.getInstance("AES");
		} catch (NoSuchAlgorithmException e) {
			if(Pblog.INIT)Pblog.INIT(e);
			throw new RuntimeException(e);
		}
        kgen.init(128, new SecureRandom(/*pkey.getBytes()*/));
        //SecretKey secretKey = kgen.generateKey();
        //byte[] enCodeFormat = secretKey.getEncoded();
        //byte[] key = kgen.generateKey().getEncoded();
        //SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
        //Cipher cipher = Cipher.getInstance("AES");// 创建密码器
        return kgen.generateKey(); 
 	}
	
	public int encode(ByteBuffer one) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
		int s = encode.doFinal(one.array(), one.position()+one.arrayOffset(), one.remaining(), one.array(), one.position()+one.arrayOffset());
		one.limit(one.position()+s);
		return s;
	}
	public int encode(ByteBuffer input,ByteBuffer output) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
		return encode.doFinal(input, output);
	}
	/**
	 * 通过应原来大小，返回加密后大小;
	 */
	public int outputLength(int inputLength) {
//		int r = originalLength%key.length;
//		if(r!=0)return originalLength+(key.length-r);
//		return originalLength;
		return encode.getOutputSize(inputLength);
	}
	public int decode(ByteBuffer one) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
		int s = decode.doFinal(one.array(), one.position()+one.arrayOffset(), one.remaining(), one.array(), one.position()+one.arrayOffset());
		one.limit(one.position()+s);
		return s;
	}
	public int decode(ByteBuffer input,ByteBuffer output) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
		return decode.doFinal(input, output);
	}
	/**
	 * 必须要等于大于 ，并且为此数的倍数才能开始解压;
	 */
//	public int blockSize() {
//		return decode.getBlockSize();
//	}

	
	public SecretKey getKey() {
		return key;
	}

}
